package spark.network;

import java.net.InetSocketAddress;
import java.net.DatagramPacket;

import spark.network.protocol.Base;
import spark.network.protocol.Response;
import spark.math.Vector2;

public class Util {
	public static byte[] makeBytes(short value) {
		return new byte[]{
				(byte) (value >>> 8),
				(byte) value};
	}

	public static short makeShort(byte[] b, int offset) {
		return (short) (
				(b[offset] << 8) +
				(b[offset + 1] & 0xFF));

	}

	public static byte[] makeBytes(int value) {
		return new byte[]{
				(byte) (value >>> 24),
				(byte) (value >>> 16),
				(byte) (value >>> 8),
				(byte) value};
	}

	public static int makeInt(byte[] b, int offset) {
		return (b[offset] << 24) +
		       ((b[offset + 1] & 0xFF) << 16) +
		       ((b[offset + 2] & 0xFF) << 8) +
		       (b[offset + 3] & 0xFF);

	}

	public static byte[] makeBytes(float value) {
		return makeBytes(Float.floatToIntBits(value));
	}

	public static float makeFloat(byte[] b, int offset) {
		return Float.intBitsToFloat(makeInt(b, offset));
	}

	public static byte[] makeBytes(long value) {
		return new byte[]{
				(byte) (value >>> 56),
				(byte) (value >>> 48),
				(byte) (value >>> 40),
				(byte) (value >>> 32),
				(byte) (value >>> 24),
				(byte) (value >>> 16),
				(byte) (value >>> 8),
				(byte) value};
	}

	public static long makeLong(byte[] b, int offset) {
		return ((long) b[offset] << 56) +
		       ((long) (b[offset + 1] & 0xFF) << 48) +
		       ((long) (b[offset + 2] & 0xFF) << 40) +
		       ((long) (b[offset + 3] & 0xFF) << 32) +
		       ((long) (b[offset + 4] & 0xFF) << 24) +
		       ((long) (b[offset + 5] & 0xFF) << 16) +
		       ((long) (b[offset + 6] & 0xFF) << 8) +
		       (long) (b[offset + 7] & 0xFF);
	}

	public static byte[] makeBytes(Vector2 value) {
		byte[] x = makeBytes(value.x);
		byte[] y = makeBytes(value.y);
		return new byte[] {x[0], x[1], x[2], x[3], y[0], y[1], y[2], y[3]};
	}

	public static Vector2 makeVector2(byte[] b, int offset) {
		return new Vector2(makeFloat(b, offset), makeFloat(b, offset + 4));
	}

	public static void arraycopy(byte[] src, int srcOffset,
	                             byte[] dest, int destOffset) {
		System.arraycopy(src, srcOffset, dest, destOffset, src.length);
	}

	public static void arraycopy(byte[] src, int srcOffset,
	                             byte[] dest, int destOffset,
	                             int length) {
		System.arraycopy(src, srcOffset, dest, destOffset, length);
	}

	public static InetSocketAddress extractInetSocketAddress(DatagramPacket packet) {
		return new InetSocketAddress(packet.getAddress(), packet.getPort());
	}

	public static byte[] createBuffer() {
		return new byte[Base.MAX_BUFFER_SIZE];
	}

	public static DatagramPacket createPacket(Base packet, InetSocketAddress destination) {
		byte[] buffer = Util.createBuffer();
		packet.getBytes(buffer);
		return new DatagramPacket(buffer, packet.getSize(), destination.getAddress(), destination.getPort());
	}
}
